deno lintのJavaScriptプラグインサポートについて
#Deno #deno_lint #ESTree
はじめに
deno lintコマンドにプラグインシステムが導入されています (Deno v2.2)
試しにプラグインを書いてみたので、こちらを例に記載します (deno-lint-plugin-extra-rules)
設定
deno.jsonのlint.pluginsでプラグインを指定します
code:deno.json
{
"lint": {
"plugins": "jsr:@uki00a/deno-lint-plugin-extra-rules@0.6.0"
}
}
ローカルファイルへのパスに加え、jsrやnpmで公開されたパッケージをプラグインとして利用することもできるようです
プラグインの記述について
プラグイン
Deno.lint.Pluginインターフェースを実装したオブジェクトをdefault exportします
code:mod.ts
const plugin: Deno.lint.Plugin = {
name: "deno-lint-plugin-extra-rules",
rules: {
// ルールの一覧...
},
};
export default plugin;
ルールの記述
Deno.lint.Ruleという型で定義されており、以下のようにcreateメソッドを定義する必要があります
code:mod.ts
const plugin: Deno.lint.Plugin = {
name: "deno-lint-plugin-extra-rules",
rules: {
// ...
"prefer-node-assert-strict": {
create: (ctx) => {
const visitor = {
"ImportDeclarationsource.value=node:assert": (
node: Deno.lint.ImportDeclaration,
) => {
ctx.report({
node,
message:
"node:assert/strict should be used instead of node:assert.",
fix: (fixer) => {
return fixer.replaceText(node.source, "node:assert/strict");
},
});
},
};
return visitor;
}
}
},
};
createメソッドの引数にはDeno.lint.RuleContextオブジェクトが渡され、これを介してエラーの報告などの様々な処理を行うことができます
createメソッドはDeno.lint.LintVisitorオブジェクトを返却する必要があります。このオブジェクトには関心のあるノード(Deno.lint.Node)の種別を指定するセレクタをキー、そのノードを処理するための関数を値として指定します
code:plugin.ts
const visitor = {
"ImportDeclarationsource.value=node:assert": (
node: Deno.lint.ImportDeclaration,
) => {
ctx.report({
node,
message:
"node:assert/strict should be used instead of node:assert.",
fix: (fixer) => {
return fixer.replaceText(node.source, "node:assert/strict");
},
});
},
};
return visitor;
上記のようにCSSセレクターライクな構文によって柔軟にノードの指定が可能です
各種ノードの形式はTSESTree (@typescript-eslint/typescript-estree)に準拠しているようです
エラーを報告したい場合は、Deno.lint.RuleContext#reportにDeno.lint.ReportDataオブジェクトを渡す必要があります (最低限、messageプロパティーの指定が必須です)
テストについて
Deno.lint.runPluginというAPIが提供されており、引数としてDeno.lint.Plugin、ファイル名、Lint対象のソースコードの3つを受け取り、Promise<Array<Deno.lint.Diagnostic>>を返却してくれるため、テストにおいて便利です
コミュニティプラグイン
lume/lint.ts - Lumeが提供しているプラグイン
deno-lint-plugin-extra-rules
その他
denoland/std/_tools/lint_plugin.ts - deno_stdの内部で使用されているプラグイン
@std/testing/unstable-snapshot - 内部的にdeno lintのプラグインの仕組みが活用されています
変更
Deno v2.1.5
1. feat(unstable): add JS linting plugin infrastructure (denoland/deno#27416)
Deno[Deno.internal].runLintPluginという内部APIが追加
2. feat(unstable): support selectors in JS lint plugins (denoland/deno#27452)
3. fix(unstable): don't error on non-existing attrs or type attr (denoland/deno#27456)
Deno v2.2
4. feat(lint): add JavaScript plugin support (denoland/deno#27203)
プラグインシステムが正式に導入